
package org.snaker.engine.impl;

import cn.easyplatform.contexts.Contexts;
import cn.easyplatform.support.scripting.RhinoScriptable;
import cn.easyplatform.support.scripting.ScriptUtils;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.RhinoException;
import org.mozilla.javascript.Wrapper;
import org.snaker.engine.Expression;

import java.util.Map;
import java.util.Map.Entry;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class RhinoExpression implements Expression {

	@Override
	public <T> T eval(Class<T> T, String expr, Map<String, Object> args) {
		RhinoScriptable scope = null;
		Context cx = Context.enter();
		try {
			scope = new RhinoScriptable();
			scope.initStandardObjects(cx, false);
			for (Entry<String, Object> entry : args.entrySet())
				scope.setVariable("$" + entry.getKey(), entry.getValue());
			Object result = cx.evaluateString(scope, expr.trim(), "", 1, null);
			if (result instanceof Wrapper)
				return T.cast(((Wrapper) result).unwrap());
			else
				return T.cast(result);
		} catch (RhinoException ex) {
			throw ScriptUtils.handleScriptException(
					Contexts.getCommandContext(), ex);
		} finally {
			Context.exit();
			scope.clear();
			scope = null;
		}
	}

}
